package com.reviling.filamentandroid

import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.View
import android.widget.SeekBar
import android.widget.SeekBar.OnSeekBarChangeListener
import androidx.appcompat.app.AppCompatActivity
import androidx.core.math.MathUtils
import com.reviling.filamentandroid.databinding.ActivityMainBinding


class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    private var customViewer: CustomViewer = CustomViewer()

    private var rotation = 120.0f//全部部位旋转,第一条进度条
    private var upDownPitch = 90.0f//前板上下俯仰，第二条进度条
    private var leftRightPitch = 90.0f//前板左右俯仰，第三条进度条

    //基础俯仰数，也就是进度条为0时的数目
    private val pitchProgressGapBase = 75

    //旋转和俯仰可以变化的最大角度
    private val maxRotation = 360
    private val maxPitch = 30


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        binding.userHint.visibility = View.GONE
        //都设置为1000即可，其他的由这边做处理
        binding.intBright.seekbarLight.max = maxRotation//最大值
        binding.intBright2.seekbarLight.max = maxPitch//最大值
        binding.intBright3.seekbarLight.max = maxPitch//最大值
        //全部旋转
        binding.intBright.seekbarLight.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
                if (fromUser) {//如果是用户滑动则为true,否则是false
                    rotation = progress.toFloat()
                    customViewer.setDegrees(rotation, upDownPitch, leftRightPitch)
                }
                Log.d("seekBar测试", "seebar1是否来自于用户的滑动：$fromUser,progress:${progress}")
            }

            override fun onStartTrackingTouch(seekBar: SeekBar) {
            }

            override fun onStopTrackingTouch(seekBar: SeekBar) {
            }
        })
        //前板上下俯仰
        binding.intBright2.seekbarLight.setOnSeekBarChangeListener(object :
            OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
                if (fromUser) {//如果是用户滑动则为true,否则是false
                    upDownPitch = progress + pitchProgressGapBase.toFloat()
                    customViewer.setDegrees(rotation, upDownPitch, leftRightPitch)
                }
                Log.d("seekBar测试", "seebar2是否来自于用户的滑动：$fromUser,progress:${progress}")
            }

            override fun onStartTrackingTouch(seekBar: SeekBar) {
            }

            override fun onStopTrackingTouch(seekBar: SeekBar) {
            }
        })
        //前板左右俯仰
        binding.intBright3.seekbarLight.setOnSeekBarChangeListener(object :
            OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
                if (fromUser) {//如果是用户滑动则为true,否则是false
                    leftRightPitch = progress + pitchProgressGapBase.toFloat()
                    customViewer.setDegrees(rotation, upDownPitch, leftRightPitch)
                }
                Log.d("seekBar测试", "seebar2是否来自于用户的滑动：$fromUser,progress:${progress}")
            }

            override fun onStartTrackingTouch(seekBar: SeekBar) {
            }

            override fun onStopTrackingTouch(seekBar: SeekBar) {
            }
        })
        //初始化glb
        initGltf()
//        initKotlinExtendFun()
    }

    private fun initGltf() {
        customViewer.run {
            loadEntity()
            setSurfaceView(requireNotNull(binding.surfaceView))

            //directory and model each as param
//            loadGlb(this@MainActivity, "grogu", "grogu")
            loadGlb(this@MainActivity, "grogu", "pd-3")
            //loadGltf(this@MainActivity, "warcraft", "scene");
            //directory and model as one
//            loadGlb(this@MainActivity, "grogu/eren-hiphop-dance");
//            loadGlb(this@MainActivity, "grogu/grogu");
//            loadGlb(this@MainActivity, "grogu/manghe01");
//            loadGlb(this@MainActivity, "other/BusterDrone");
//            loadGlb(this@MainActivity, "other/DamagedHelmet");

            //Enviroments and Lightning (OPTIONAL)
//            loadIndirectLight(this@MainActivity, "venetian_crossroads_2k")
//            loadEnviroment(this@MainActivity, "venetian_crossroads_2k");
//            这两个是自定义的颜色背景，替代loadIndirectLight的效果
            loadSkybox()
            loadLight(false)
            loadDefault()
            //是否允许旋转和俯仰
//            setLateralEnable(false)
//            setPitchEnable(true)
            setOnTouchDireListener(object : CustomViewer.OnTouchDireListener {
                override fun onTouchDire(isRotation: Boolean, moveStatus: Int, f: Float): Float {
                    if (isRotation && moveStatus == 0) {//是否是全部在旋转
                        rotation -= f / 6.0f
                        rotation = MathUtils.clamp(
                            rotation,
                            0f, maxRotation.toFloat()
                        )//直接0-100即可,其他数目也可以，自己看,作用是把值固定在这个范围内
                        Log.d("计算结果", "rotation 初始返回值：$f,计算后的值：$rotation")
                        binding.intBright.seekbarLight.progress = rotation.toInt()
                        return rotation
                    }
                    //俯仰
                    if (moveStatus == 1) {//前板左右俯仰
                        leftRightPitch -= f / 6.0f
                        leftRightPitch = MathUtils.clamp(
                            leftRightPitch,
                            pitchProgressGapBase.toFloat(),
                            (pitchProgressGapBase + maxPitch).toFloat()
                        )//直接0-100即可，其他数目也可以，自己看， 作用是把值固定在这个范围内
                        Log.d("计算结果", "pitch 初始返回值：$f,计算后的值：$leftRightPitch")
                        binding.intBright3.seekbarLight.progress = (leftRightPitch).toInt()
                        return leftRightPitch
                    } else {//moveStatus==2，前板上下俯仰
                        upDownPitch += f / 6.0f
                        upDownPitch = MathUtils.clamp(
                            upDownPitch,
                            pitchProgressGapBase.toFloat(),
                            (pitchProgressGapBase + maxPitch).toFloat()
                        )//直接0-100即可，其他数目也可以，自己看， 作用是把值固定在这个范围内
                        Log.d("计算结果", "pitch 初始返回值：$f,计算后的值：$upDownPitch")
                        binding.intBright2.seekbarLight.progress = (upDownPitch).toInt()
                        return upDownPitch
                    }
                }

                override fun onTouchPer200ms(f: Float, f2: Float) {//这里保存数据到数据库
                }

                override fun onTouchStart() {
                }

                override fun onTouchStop() {
                }
            })
//            初始角度，暂且这样来调节
            Handler(Looper.getMainLooper()).postDelayed({
                setDegrees(rotation, upDownPitch, leftRightPitch)
                binding.intBright.seekbarLight.progress = rotation.toInt()
                binding.intBright2.seekbarLight.progress =
                    (upDownPitch - pitchProgressGapBase).toInt()
                binding.intBright3.seekbarLight.progress =
                    (leftRightPitch - pitchProgressGapBase).toInt()
            }, 50)
        }
    }

    override fun onResume() {
        super.onResume()
        customViewer.onResume()
    }

    override fun onPause() {
        super.onPause()
        customViewer.onPause()
    }

    override fun onDestroy() {
        super.onDestroy()
        customViewer.onDestroy()
    }

    /**
     * 扩展函数的一些测试
     */
    private fun initKotlinExtendFun() {
        //测试repeat
        repeat(10) { index ->
            Log.d("测试", "输出的是下标：$index")
        }
        //测试run
        val number: Int? = if (upDownPitch == 0.0f) 1000 else null
        //number不空的时候会执行run里面的内容，这点和let一样
        val result = number?.run {
            Log.d("测试", "result第一个是$this")//这里会输出1000
            2000
        }.run {
            Log.d("测试", "result第二个是$this")//这里会输出2000
            3000
        }.run {
            Log.d("测试", "result第三个是$this")//这里会输出3000
            5000//最后一个run这里如果不赋值，那么result就会变为1返回去，奇怪，不应该是3000？
        }
        Log.d("测试", "run以外被返回的最终result是$result")//这里会输出5000
        //测试also
        val result2 = number?.run {
            Log.d("测试", "result2第一个是$this")//这里会输出1000
            2000
        }.also {
            Log.d("测试", "result2第二个是$it")//这里会输出2000
            3000 + it!!
        }.also {
            it?.times(20)//不空则乘以20
            Log.d("测试", "result2第三个是$it")//这里也会输出2000
        }
        Log.d("测试", "run以外被返回的最终result2是$result2")//这里也会输出2000,所以also是返回it本身，不返回最后一行
        //测试let
        val result3 = number?.let {
            Log.d("测试", "result3第一个是$it")//这里会输出1000
            2000
        }.let {
            Log.d("测试", "result3第二个是$it")//这里会输出2000
            it?.minus(30)//不空则减去30
        }.let {
            Log.d("测试", "result3第三个是$it")//这里会输出1970
            it?.times(20)//不空则乘以20
        }
        Log.d("测试", "run以外被返回的最终result3是$result3")//这里会输出39400，所以let是返回最后一行作为结果
        //测试with
        val result4 = with(12) {
            times(20)
        }
        Log.d("测试", "run以外被返回的最终result4是$result4")//所以with也是返回最后一行
        //其他用的多，早就会的就不测试了比如apply,let会一些,with会一些(测试了返回值)
    }


}